﻿using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using System.Runtime.InteropServices;
using EnvDTE;
using Microsoft.VisualStudio.SharePoint;
using System.IO;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.Win32;
using System.Security.AccessControl;
using System.Reflection;

namespace CodeCounsel.SharePoint.DevTools
{
    static class ProjectUtilities
    {
        public static DTE GetDTE()
        {
            return (DTE)Package.GetGlobalService(typeof(DTE));
        }

        public static ISharePointProjectService GetSharePointService()
        {
            return (ISharePointProjectService)Package.GetGlobalService(typeof(ISharePointProjectService));
        }

        public static string GetSharePointInstallRoot()
        {
            return GetSharePointService().SharePointInstallPath;
        }

        public static string GetAssemblyName(ISharePointProject project)
        {
            string outputFullPath = project.OutputFullPath;
            if (File.Exists(outputFullPath))
            {
                return AssemblyName.GetAssemblyName(outputFullPath).FullName;
            }
            return Path.GetFileNameWithoutExtension(outputFullPath);
        }

        public static string GetOfficeServerInstallRoot()
        {
            RegistryKey key = Registry.LocalMachine.OpenSubKey(
                @"SOFTWARE\Microsoft\Office Server\14.0",
                RegistryKeyPermissionCheck.ReadSubTree,
                RegistryRights.QueryValues);
            return (string)key.GetValue("InstallPath");
        }

        public static bool IsSharePointProject(IVsHierarchy h)
        {
            IVsAggregatableProject project = h as IVsAggregatableProject;
            if (project != null)
            {
                string guidString = null;
                project.GetAggregateProjectTypeGuids(out guidString);
                IEnumerable<Guid> guids = guidString.Split(';').Select(s => new Guid(s));
                return guids.Contains(VSPackageGuids.ProjectType_SharePoint);
            }
            return false;
        }

        public static IEnumerable<IVsHierarchy> GetSelectedProjects()
        {
            List<IVsHierarchy> list = new List<IVsHierarchy>();
            IntPtr hierarchyPointer = IntPtr.Zero;
            uint itemCount = 0;
            IntPtr ppSC = IntPtr.Zero;
            int singleItemPointer = 0;
            IVsMultiItemSelect multiSelect = null;
            try
            {
                IVsMonitorSelection monitorSelection = (IVsMonitorSelection)Package.GetGlobalService(typeof(SVsShellMonitorSelection));
                ErrorHandler.ThrowOnFailure(monitorSelection.GetCurrentSelection(
                    out hierarchyPointer, out itemCount, out multiSelect, out ppSC));
                if (hierarchyPointer != IntPtr.Zero)
                {
                    IVsHierarchy hierarchy = (IVsHierarchy)Marshal.GetObjectForIUnknown(hierarchyPointer);
                    list.Add(hierarchy);
                }
                else if (multiSelect != null)
                {
                    ErrorHandler.ThrowOnFailure(multiSelect.GetSelectionInfo(out itemCount, out singleItemPointer));
                    VSITEMSELECTION[] items = new VSITEMSELECTION[itemCount];
                    ErrorHandler.ThrowOnFailure(multiSelect.GetSelectedItems(0, itemCount, items));
                    list.AddRange(items.Select(item => item.pHier));
                }
                return list;
            }
            finally
            {
                if (hierarchyPointer != IntPtr.Zero)
                {
                    Marshal.Release(hierarchyPointer);
                }
                if (ppSC != IntPtr.Zero)
                {
                    Marshal.Release(ppSC);
                }
            }
        }

        public static string UnTokenize(ISharePointProjectFeature feature, string tokenString)
        {
            if (feature != null)
            {
                tokenString = tokenString.Replace("$SharePoint.Project.FileNameWithoutExtension$", Path.GetFileNameWithoutExtension(feature.Project.FullPath));
                tokenString = tokenString.Replace("$SharePoint.Feature.FileNameWithoutExtension$", Path.GetFileNameWithoutExtension(feature.FullPath));
            }
            return tokenString;
        }
    }
}
